﻿using System;
using Pfz.Threading.Unsafe;

namespace Pfz.Threading
{
	/// <summary>
	/// Class that creates a thread to run Runnables as messages. It only creates 
	/// one thread to process all messages. Use it only when you know you want to
	/// process many messages asynchronously, but don't want (or can't) use ThreadPool 
	/// threads.
	/// </summary>
	public sealed class RunnableRunner:
		DisposeAssurerBase<UnsafeRunnableRunner>
	{
		/// <summary>
		/// Creates a new instance of this class.
		/// </summary>
		public RunnableRunner(IRunnable cleanup=null):
			base(new UnsafeRunnableRunner(cleanup))
		{
		}

		/// <summary>
		/// Gets the number of action still unprocessed.
		/// </summary>
		public int PendingCount
		{
			get
			{
				return Value.PendingCount;
			}
		}

		/// <summary>
		/// Post the given action to be run.
		/// </summary>
		public void Run(IRunnable runnable)
		{
			var runner = Value;
			if (runner == null)
				throw new ObjectDisposedException(GetType().FullName);

			runner.Run(runnable);
		}

		/// <summary>
		/// Post the given action to be run.
		/// </summary>
		public void Run<T>(IRunnable<T> runnable, T value)
		{
			var runner = Value;
			if (runner == null)
				throw new ObjectDisposedException(GetType().FullName);

			runner.Run(runnable, value);
		}
	}
}
